﻿/*
 * @Autor: PK
 * @Date: 2021/5/20 17:10:26
 * @Description: OptimizationNetwork
 */

using ShkSimulation.core.optimization.algorithm;
using ShkSimulation.core.optimization.extractor;
using ShkSimulation.core.optimization.extractor.result;
using ShkSimulation.core.optimization.impl;
using ShkSimulation.core.optimization.interfaces;
using ShkSimulation.core.optimization.variable;
using ShkSimulation.core.template;

namespace ShkSimulation.core.optimization {

    public class DefaultOptimizationNetwork : Optimization {

        public DefaultOptimizationNetwork(CloneableNetwork realNetworkTemplate, 
            OptimizationAlgorithm algorithm, 
            ResultEvaluationStrategy evaluationStrategy,
            NamedCellPointGroup decision,
            NamedCellPointGroup target,
            OptimizationConfig config) {
            
            RealNetworkTemplate = realNetworkTemplate;
            Algorithm = algorithm;
            EvaluationStrategy = evaluationStrategy;
            Config = config;

            TargetVariableExtractor = new DefaultTargetVariableExtractor(target);
            DecisionVariableExtractor = new NamedMatrixDecisionVariableExtractor(decision);
            DecisionVariableConverter = new DoubleDecisionVariableConverter();
            UniqueIdGenerator = new OrderedUniqueIdGenerator();
            var temp = DecisionVariableExtractor.ExtractNamedDecisionVariables(RealNetworkTemplate.NetworkInput);
            VariableVectorTemplate = DecisionVariableConverter.Convert(temp);
        }

        public CloneableNetwork RealNetworkTemplate { get; set; }
        public OptimizationConfig Config { get; set; }
        public OptimizationAlgorithm Algorithm { set; get; }
        public ResultEvaluationStrategy EvaluationStrategy { get; set; }

        public NamedDecisionVariableExtractor DecisionVariableExtractor { get;set; }
        public TargetVariableExtractor TargetVariableExtractor { get; set; }
        public ParallelUniqueIdGenerator UniqueIdGenerator { get; set; }
        public DecisionVariableConverter<double> DecisionVariableConverter { get; set; } 
        public DecisionVariableVector<double> VariableVectorTemplate { get; set; }
        
        public EvaluateResult BestOne { get; set; }

        public void Optimize() {
            Algorithm.RunWithOptimization(this);
        }

    }
}
